#include "ui/attack/BWDefenderInfo.h"
#include "gui/GuiFactory.h"
#include "utils/ScreenUtils.h"
#include "utils/StringUtils.h"
#include "localization/Localization.h"
#include "gui/IconWithText.h"
#include "rating/entities/RatingInfo.h"
#include "scene/SceneController.h"
#include "character/CharacterData.h"
#include "gui/Tooltip.h"
#include "gui/action/FadeTo.h"
#include "animation/Animation.h"
#include "sound/SoundManager.h"
#include "location/GameLocationController.h"
#include "rating/entities/SquadTourneyData.h"
#include "effects/manager/LocationEffectsManager.h"

BWDefenderInfo::BWDefenderInfo():
	paymentBonusButton(nullptr),
	paymentBonusEffectAnimation(nullptr)
{
}

BWDefenderInfo* BWDefenderInfo::create( const char* name, int level, int winPoints, int losePoints ) {
	BWDefenderInfo* result = new BWDefenderInfo();
	if ( result && result->init( name, level, winPoints, losePoints ) ) {
		result->autorelease();
		return result;
	}
	CC_SAFE_DELETE(result);
	return nullptr;
}

void BWDefenderInfo::fitToSize( CCNode* const element, const float size ) {
	const float realSize = ScreenUtils::getScale() / 1.4f * size;
	const float scale = MIN( realSize / element->getContentSize().width, realSize / element->getContentSize().height );
	element->setScale( scale );
}

void BWDefenderInfo::fitToSize( CCNode* const element, const CCSize& size ) {
	const float realWidth = ScreenUtils::getScale() / 1.4f * size.width;
	const float realHeight = ScreenUtils::getScale() / 1.4f * size.height;
	const float scale = MIN( realWidth / element->getContentSize().width, realHeight / element->getContentSize().height );
	element->setScale( scale );
}

bool BWDefenderInfo::init( const char* name, int level, int winPoints, int losePoints ) {
	float contentHeight = 0;

	const float scale = ScreenUtils::getScale() / 1.4f;
	const float fontSize = 64*scale;
	float lastY = 0;
	bool isBattleWithPlayer = SceneController::getCurrentLocationController()->getLocationType() == LocationTypeEnum::PVP;
	bool isFirstPvpWin = CharacterData::getPlayerData()->isFirstPvpWinBonusAllowed() && isBattleWithPlayer;
	bool isBonusRating = LocationEffectsManager::getInstance()->contains(LocationEffectComponent::Type::PVP_RATING_MODIFIER, false) && isBattleWithPlayer;
	bool isBonusTourneyScore = LocationEffectsManager::getInstance()->contains(LocationEffectComponent::Type::SQUAD_TOURNEY_SCORES, false) && isBattleWithPlayer;

	int winPointsWithoutBonuses = winPoints;
	if (isFirstPvpWin) {
		winPoints = (int)floorf(winPoints * CharacterData::FIRST_PVP_WIN_FACTOR);
	}
	if (isBonusRating) {
		winPoints += LocationEffectsManager::getInstance()->getAdditionForValue(winPointsWithoutBonuses, LocationEffectComponent::Type::PVP_RATING_MODIFIER, false);
	}

	int winTourneyScoreWithoutBonuses = SquadTourneyData::getInstance()->getScoreForWin(3);
	int winTourneyScore = winTourneyScoreWithoutBonuses;
	if (isFirstPvpWin) {
		winTourneyScore = (int)floorf(winTourneyScore * CharacterData::FIRST_PVP_WIN_FACTOR);
	}
	if (isBonusTourneyScore) {
		winTourneyScore += LocationEffectsManager::getInstance()->getAdditionForValue(winTourneyScoreWithoutBonuses, LocationEffectComponent::Type::SQUAD_TOURNEY_SCORES, false);
	}

	int loseTourneyScore = -SquadTourneyData::getInstance()->getScoreForLose(3);

	if ( losePoints != 0 ) {
		
		IconWithText *ratingTrophy = IconWithText::create(
			"gui/main_ui/icon_medal.png", 
			67*scale, 
			std::to_string( losePoints ), 
			fontSize
		);
		ratingTrophy->setOrientation( OrientationRight );
		ratingTrophy->setSpacing(6*scale);
		ratingTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
		ratingTrophy->setPosition( CCPoint( -ratingTrophy->getContentSize().width, lastY ) );
		addChild( ratingTrophy );

		if (RatingInfo::squads.getTourney().playerIsTourneyParticipant() && isBattleWithPlayer) {
			IconWithText *tourneyScoreTrophy = IconWithText::create(
				"gui/main_ui/icon_cup.png", 
				67 * scale,
				std::to_string(loseTourneyScore),
				fontSize
			);
			tourneyScoreTrophy->setOrientation( OrientationRight );
			tourneyScoreTrophy->setSpacing(6*scale);
			tourneyScoreTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
			tourneyScoreTrophy->setPosition(CCPoint(ratingTrophy->getPositionX() - 8 * scale - tourneyScoreTrophy->getContentSize().width, lastY));
			addChild( tourneyScoreTrophy );
		}
		
		lastY += ratingTrophy->getContentSize().height + 5 * scale;

		TextLabel * defeatLabel = TextLabel::create( Localization::tr("LID Defeat:"), 40*scale, ccWHITE, CCSize(0,50*scale), LabelTextStyle::SHADOW );
		defeatLabel->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
		defeatLabel->setPosition( CCPoint( -defeatLabel->getContentSize().width, lastY ) );
		addChild( defeatLabel );

		lastY += defeatLabel->getContentSize().height + 20 * scale;
		contentHeight = lastY;
	}
	
	if ( winPoints != 0 ) {

		std::string winPointsText = std::to_string(winPointsWithoutBonuses);
		std::string winTourneyScoreText = std::to_string(winTourneyScoreWithoutBonuses);
		if (isFirstPvpWin || isBonusRating) {
			winPointsText = winPointsText + "+" + std::to_string(winPoints - winPointsWithoutBonuses);
		}
		if (isFirstPvpWin || isBonusTourneyScore) {
			winTourneyScoreText = winTourneyScoreText + "+" + std::to_string(winTourneyScore - winTourneyScoreWithoutBonuses);
		}

		IconWithText *ratingTrophy = IconWithText::create(
			"gui/main_ui/icon_medal.png",
			67 * scale,
			winPointsText.c_str(),
			BBFont::WhiteShadow(14)
		);
		ratingTrophy->setOrientation( OrientationRight );
		ratingTrophy->setSpacing(6*scale);
		ratingTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
		ratingTrophy->setPosition(CCPoint(-ratingTrophy->getContentSize().width, lastY));
		addChild( ratingTrophy );

		if (RatingInfo::squads.getTourney().playerIsTourneyParticipant() && isBattleWithPlayer) {
			IconWithText *tourneyScoreTrophy = IconWithText::create(
				"gui/main_ui/icon_cup.png", 
				67 * scale,
				winTourneyScoreText.c_str(),
				BBFont::WhiteShadow(14)
			);
			tourneyScoreTrophy->setOrientation( OrientationRight );
			tourneyScoreTrophy->setSpacing(6*scale);
			tourneyScoreTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
			tourneyScoreTrophy->setPosition(CCPoint(ratingTrophy->getPositionX() - 8 * scale - tourneyScoreTrophy->getContentSize().width, lastY));
			addChild( tourneyScoreTrophy );

			//lastY += tourneyScoreTrophy->getContentSize().height + 5 * scale;
		}


		lastY = ratingTrophy->getPositionY() + ratingTrophy->getContentSize().height * ratingTrophy->getScaleY() + 11*scale;
		contentHeight = lastY;
	}

	oilTrophy = IconWithText::create(CurrencyEntity::OIL->getIcon(), 67 * scale, "", fontSize);
	oilTrophy->setOrientation( OrientationRight );
	oilTrophy->setSpacing(6*scale);
	oilTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
	oilTrophy->setPositionY( lastY );
	addChild( oilTrophy );

	lastY = oilTrophy->getPositionY() + oilTrophy->getContentSize().height * oilTrophy->getScaleY();
	contentHeight = lastY;

	goldTrophy = IconWithText::create(CurrencyEntity::GOLD->getIcon(), 67 * scale, "", fontSize);
	goldTrophy->setOrientation( OrientationRight );
	goldTrophy->setSpacing(6*scale);
	goldTrophy->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
	goldTrophy->setPositionY( lastY );
	addChild( goldTrophy );

	lastY = goldTrophy->getPositionY() + goldTrophy->getContentSize().height * goldTrophy->getScaleY();
	contentHeight = lastY;

	TextLabel * availableLootLabel = TextLabel::create( Localization::tr("LID Available Loot:"), 40*scale, ccWHITE, CCSize(0,50*scale), LabelTextStyle::SHADOW );
	availableLootLabel->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
	availableLootLabel->setPosition( CCPoint( -availableLootLabel->getContentSize().width, lastY ) );
	addChild( availableLootLabel );

	lastY = availableLootLabel->getPositionY() + availableLootLabel->getContentSize().height * availableLootLabel->getScaleY();
	contentHeight = lastY;

	// Иконка уровня и уровень
	CCSprite * levelIcon = GuiFactory::createSprite("gui/main_ui/icon_star_exp.png");
	levelIcon->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
	fitToSize( levelIcon, 134 );
	addChild(levelIcon);

	const CCSize levelLabelSize(levelIcon->getContentSize().width * levelIcon->getScaleX(), levelIcon->getContentSize().height * levelIcon->getScaleY() );
	levelLabel = TextLabel::create(StringUtils::format( "%i", level ).c_str(), fontSize, ccc3(255, 255, 255), levelLabelSize, LabelTextStyle::SHADOW);
	addChild(levelLabel);

	// Имя того на кого мы напали
	nameLabel = TextLabel::create( name, fontSize, ccWHITE, CCSize( 0, levelIcon->getContentSize().height * levelIcon->getScaleY() ), LabelTextStyle::SHADOW );
	nameLabel->setAnchorPoint(CCPoint::ANCHOR_BOTTOM_LEFT);
	nameLabel->setPosition( CCPoint(-nameLabel->getContentSize().width, lastY) );
	addChild(nameLabel);

	levelIcon->setPosition( CCPoint(nameLabel->getPositionX() - 11*scale - levelIcon->getContentSize().width*levelIcon->getScaleX(), lastY ) );
	levelLabel->setPosition( CCPoint( levelIcon->getPositionX() - 10*scale, levelIcon->getPositionY() ) );

	lastY = levelIcon->getPositionY() + levelIcon->getContentSize().height * levelIcon->getScaleY();
	contentHeight = lastY;

	setContentSize( CCSize(nameLabel->getPositionX() + nameLabel->getContentSize().width, contentHeight) );

	return true;
}

void BWDefenderInfo::setGoldValue(int value){
	goldTrophy->setString(StringUtils::formatInt(value));
	goldTrophy->setPositionX(-goldTrophy->getContentSize().width);
}

void BWDefenderInfo::setOilValue(int value){
//	const float scale = ScreenUtils::getScale() / 1.4f;
	oilTrophy->setString(StringUtils::formatInt(value));
	oilTrophy->setPositionX(-oilTrophy->getContentSize().width/* - 10*scale */);
}

void BWDefenderInfo::setName(const char* name){
	nameLabel->setString(name);
}

void BWDefenderInfo::setLevel(int level){
	levelLabel->setString( StringUtils::format( "%i", level ).c_str() );
}

void BWDefenderInfo::showPaymentBonusButton(){

	if(paymentBonusButton){
		//уже есть кнопка, нам не интересно
		return;
	}

	ActivePaymentBonus & currentActiveBonus = CharacterData::getPlayerData()->getActivePaymentBonus();

	if(!currentActiveBonus.isActive()){
		return;
	}

	const float scale = ScreenUtils::getScale();
	//const CCSize & size = ScreenUtils::getSize();

	paymentBonusButton = MainUIButtonWithTimer::create(
		currentActiveBonus.getCurrentBonus()->getIcon().c_str(),
		this,
		menu_selector(BWDefenderInfo::removePaymentButtonEffect),
		currentActiveBonus.getSecondsToEnd()
	);
	const float buttonScale = (scale / 1.4f) * BBGuiConst::MAIN_BUTTONS_WIDTH / paymentBonusButton->getContentSize().width;
	paymentBonusButton->setScale(buttonScale, buttonScale);
	paymentBonusButton->setPosition(CCPoint::ZERO);
	paymentBonusButton->hide();

	Tooltip * tooltip = Tooltip::create(
		paymentBonusButton,
		CCSize(500 * scale, 0),
		Localization::tr(currentActiveBonus.getCurrentBonus()->getShortDescriptionLID()),
		false,
		NULL,
		CCRect::ZERO,
		true
	);
	tooltip->setTextAlignment(kCCTextAlignmentCenter);
	tooltip->setPosition(
		-paymentBonusButton->getContentSize().width * buttonScale - 5.0f * buttonScale,
		-paymentBonusButton->getContentSize().height * buttonScale - 30.0f * buttonScale
	);
	tooltip->setBubblePosition(CCPoint(0, paymentBonusButton->getContentSize().height * buttonScale * 0.5f));
	addChild(tooltip);

	CCPoint positionFrom = convertToNodeSpace(ScreenUtils::getScreenCenterPoint()) + CCPoint(0, 100*ScreenUtils::getScale());

	CCSprite * star = GuiFactory::createSprite(currentActiveBonus.getCurrentBonus()->getIcon().c_str());
	star->setAnchorPoint( CCPoint::ANCHOR_MIDDLE );
	star->setScale( 0 );
	star->setPosition(positionFrom);
	addChild(star, 1);

	// Первая фаза, тупо показываем бонус
	CCScaleTo * scaleTo1 = CCScaleTo::create(0.15f, buttonScale * 1.7f);
	CCScaleTo * scaleTo12 = CCScaleTo::create(0.3f, buttonScale * 1.5f);
	CCDelayTime * delayTime = CCDelayTime::create(0.15f);
	CCSequence * phase1 = CCSequence::create(scaleTo1, scaleTo12, delayTime, NULL);

	// Вторая фаза, уносим и скейлим его
	ccBezierConfig config;
	CCPoint endPosition(tooltip->getPositionX() + paymentBonusButton->getContentSize().width * buttonScale * 0.5f, tooltip->getPositionY() + paymentBonusButton->getContentSize().height * buttonScale * 0.5f);
	config.endPosition = CCPoint(endPosition.x, endPosition.y + 10.0f * scale);
	config.controlPoint_1 = CCPoint(positionFrom.x, positionFrom.y);
	config.controlPoint_2 = CCPoint(positionFrom.x * 0.5f, 0.3f * positionFrom.y - 400 * scale);
	CCBezierTo * bezierTo = CCBezierTo::create(0.5f, config);
	CCMoveTo * finalMove = CCMoveTo::create(0.2f, endPosition);

	CCScaleTo * scaleTo2 = CCScaleTo::create(0.8f, buttonScale);
	CCSpawn * phase2 = CCSpawn::createWithTwoActions(CCSequence::createWithTwoActions(bezierTo, finalMove), scaleTo2);
	CCActionEase * moddedPhase2 = CCEaseInOut::create(phase2, 1.2f);

	//начнём потихонечку отображать кнопку, после подождём и удаляем саму леталку
	CCCallFunc * startDisplayButton = CCCallFuncN::create(this, callfuncN_selector(BWDefenderInfo::startDisplayingPaymentButton));
	CCDelayTime * delayAfterStartDisplayButton = CCDelayTime::create(0.1f);
	CCCallFunc * removeEffectFunc = CCCallFuncN::create(this, callfuncN_selector(BWDefenderInfo::removePaymentButtonEffect));
	CCCallFunc * startAnimationEffect = CCCallFuncN::create(this, callfuncN_selector(BWDefenderInfo::displayPaymentBonusAnimationEffect));

	CCDelayTime * delayTimeForStars = CCDelayTime::create(0.5f);

	CCSequence * resultAction = CCSequence::create(delayTimeForStars, startAnimationEffect, phase1, moddedPhase2, startDisplayButton, delayAfterStartDisplayButton, removeEffectFunc, NULL);
	star->runAction(resultAction);
}

void BWDefenderInfo::startDisplayingPaymentButton(CCNode * effect){
	ActivePaymentBonus & currentActiveBonus = CharacterData::getPlayerData()->getActivePaymentBonus();
	if(!currentActiveBonus.isActive()){
		return;
	}
	paymentBonusButton->setOpacity(0);
	paymentBonusButton->stretchRibbon();
	paymentBonusButton->setLeftSeconds(currentActiveBonus.getSecondsToEnd());
	FadeTo * fadeIn = FadeTo::create(0.1f, 0, 255);
	paymentBonusButton->runAction(fadeIn);
}

void BWDefenderInfo::removePaymentButtonEffect(CCNode * effect){
	effect->removeFromParent();
}

void BWDefenderInfo::displayPaymentBonusAnimationEffect(CCNode * effect){
	if(CharacterData::getPlayerData()->getActivePaymentBonus().isActive() && CharacterData::getPlayerData()->getActivePaymentBonus().getCurrentBonus()->getReceiveSound().size() > 0){
		SoundManager::getInstance()->playSound(CharacterData::getPlayerData()->getActivePaymentBonus().getCurrentBonus()->getReceiveSound());
	}

	CCPoint positionFrom = convertToNodeSpace(ScreenUtils::getScreenCenterPoint()) + CCPoint(0, 100*ScreenUtils::getScale());
	paymentBonusEffectAnimation = Animation::create("MedalFlash");
	paymentBonusEffectAnimation->setScale(ScreenUtils::getAbsoluteMinScale());
	paymentBonusEffectAnimation->play();
	paymentBonusEffectAnimation->getAnimationEndSignal().setListener(this, (&BWDefenderInfo::onAnimationEnd));
	paymentBonusEffectAnimation->setPosition(positionFrom);
	addChild(paymentBonusEffectAnimation, -1);
}

void BWDefenderInfo::onAnimationEnd(){
	paymentBonusEffectAnimation->removeFromParent();
	paymentBonusEffectAnimation = NULL;
}